package com.zzuli.yxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzuli.yxy.entity.Album;
import com.zzuli.yxy.entity.Singer;
import com.zzuli.yxy.entity.Song;
import com.zzuli.yxy.enumeration.AppHttpCodeEnum;
import com.zzuli.yxy.result.R;
import com.zzuli.yxy.util.TXCloudFileUtils;
import com.zzuli.yxy.mapper.SongMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zzuli.yxy.service.SongService;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;


/**
 * @auther pony
 * @create 2023-04-04 12:57
 */
@Service
public class SongServiceImpl extends ServiceImpl<SongMapper, Song> implements SongService {

    @Autowired
    private SongMapper songMapper;

    //腾讯云对象存储 路径-访问域名
    private static String url = "https://pony-1312090731.cos.ap-beijing.myqcloud.com/";
    // 图片存储的文件夹
    private static String imgPath = "yxy/images/";
    // 歌曲 MP3 存储位置
    private static String songPath = "yxy/songs/";

    /**
     * 获取音乐管理分页信息
     * @param pageCurrent 当前页
     * @param pageSize 每页条数
     * @param name 关键字 非必传
     * @return
     */
    @Override
    public R getPage(Integer pageCurrent, Integer pageSize, String name) {
        // 1、查询分页信息
        Page<Song> pageInfo = new Page<>(pageCurrent, pageSize);
        LambdaQueryWrapper<Song> qw = new LambdaQueryWrapper<>();
        qw.like(name!=null, Song::getSongName, name);
        Page<Song> songPage = songMapper.selectPage(pageInfo, qw);
        System.out.println("songPage=" + songPage);
        // 2、设置歌曲的歌手信息、专辑
        List<Song> songs = songPage.getRecords();
        for (Song song: songs) {
            // 查询歌手 一首歌的歌手可能有多个（合唱），所以这里放到 list 里
            List<Singer> singerList = songMapper.selectSingerBySongId(song.getSongId());
            List<String> singerNameList = new ArrayList<>();
            for (Singer singer : singerList) {
                singerNameList.add(singer.getSingerName());
            }
            song.setSinger(singerNameList);
            // 查询所属专辑
            Album album = songMapper.selectAlbumBySongId(song.getSongId());
            if (!Objects.isNull(album)){
                String albumName = album.getAlbumName();
                song.setAlbum(albumName);
            }
        }

        return R.success().message("歌曲分页信息").data("songPage", songPage);
    }

    /**
     * 添加歌曲
     * @param song
     * @return
     */
    @Override
    public R addSong(Song song) {
        // 1、设置歌曲上传时间
        Album album = songMapper.selectAlbumBySongId(song.getSongId());
        if (!Objects.isNull(album)){
            if (album.getAlbumReleaseTime()!=null&&!"".equals(album.getAlbumReleaseTime())){
                song.setSongTime(album.getAlbumReleaseTime());
            }
        }else {
            //获取当前时间
            Date date = new Date();
            song.setSongTime(date);
        }

        // 2、添加歌曲
        int insert = songMapper.insert(song);
        if (insert!=1){
            return R.error().message("添加歌曲失败，系统错误，请联系管理员！");
        }
        // 3、将 id 返回
        return R.success().message("歌曲添加成功！");
    }

    /**
     * 添加歌曲-上传歌曲图片
     * @param file 图片
     * @return
     */
    @Override
    public R uploadAddImg(MultipartFile file) {
        //3、上传文件 返回值是 key，即图片重新命名的名字
        String imgName = TXCloudFileUtils.upLoad(imgPath, file);
        //4、拼接 img 访问路径，并写入数据库
        String imgUrl = url  + imgPath + imgName;
        return R.success().message("歌曲图片上传成功").data("songImgUrl", imgUrl);
    }

    /**
     * 添加歌曲-上传歌曲 歌词
     * @param file 歌词 .txt 文件
     * @return
     */
    @Override
    public R uploadAddLrc(MultipartFile file) {
        // 1、读取文件
        // 将 MultipartFile 转为 java.io.File
        File LyFile = TXCloudFileUtils.MultipartFileToFile(file);
        try(
                FileInputStream inputStream = new FileInputStream(LyFile);
                InputStreamReader read = new InputStreamReader(inputStream ,"utf-8");//考虑到编码格式
                BufferedReader bufferedReader = new BufferedReader(read);
        ) {
            // 每行的歌词
            String lineTxt;
            // 歌词 list
            ArrayList<String> LyricsList = new ArrayList<>();
            while((lineTxt = bufferedReader.readLine()) != null){
                System.out.println(lineTxt);
                LyricsList.add(lineTxt);
            }
            // 将 list 转化为 string
            String Lyrics = String.join("\\n", LyricsList) + "\\n";
            return R.success().message("歌词上传成功").data("songLyric", Lyrics);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.error(AppHttpCodeEnum.ERROR).message("歌曲-歌词文件上传失败！");
    }

    /**
     * 添加歌曲-上传歌曲 .mp3
     * @param file 歌曲 .mp3 文件
     * @return
     */
    @Override
    public R uploadAddMp3(MultipartFile file) {
        // 1、将文件上传到 云端数据桶
        String songKey = TXCloudFileUtils.upLoad(songPath, file);
        // 2、拼接 song 访问路径，返回前端
        String songUrl = url  + songPath + songKey;
        return R.success().message("歌曲 mp3 上传成功").data("songUrl", songUrl);
    }

    /**
     * 更改歌曲当前状态
     * @param status 状态码 0：正常 1：异常
     * @return
     */
    @Override
    public void setStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<Song> uw = new LambdaUpdateWrapper<>();
        uw.eq(Song::getSongId, id);
        uw.set(Song::getSongStatus, status);
        songMapper.update(null, uw);
    }

    /**
     * 根据歌曲 id，删除歌曲
     * 既要删除数据库里的歌曲基本数据
     * 又要删除 云存储桶里的 图片 MP3 文件 数据
     * @param id 歌曲id
     * @return
     */
    @Override
    public R deleteSongById(Integer id) {
        /*1、删除云存储桶里的歌曲图片
        查询数据库 得到 歌曲信息*/
        LambdaQueryWrapper<Song> selectQw = new LambdaQueryWrapper<>();
        selectQw.eq(Song::getSongId, id);
        Song selectResult = songMapper.selectOne(selectQw);
        //2、删除云存储桶里的歌曲 图片
        deleteTXCosSongImg(selectResult);

        //3、删除云存储桶里的歌曲 mp3 文件
        deleteTXCosSongMp3(selectResult);

        //4、删除数据库里歌曲基本信息
        LambdaQueryWrapper<Song> qw = new LambdaQueryWrapper<>();
        qw.eq(Song::getSongId, id);
        int deleteResult = songMapper.delete(qw);

        //5、删除歌曲 歌手的关联信息
        songMapper.deleteSingerBySongId(id);
        //6、删除歌曲 专辑的关联信息
        songMapper.deleteAlbumBySongId(id);

        //删除歌曲信息
        if (deleteResult==1){
            return R.success().message("歌曲删除成功");
        }
        return R.error().message("歌曲删除失败，系统错误，请联系管理员");
    }

    /**
     * 删除云存储桶里的歌曲 图片
     * @param song 待删除歌曲
     */
    public void deleteTXCosSongImg(Song song){
        /*最初爬虫的图片数据没有存到云存储桶 是网易的图片 不需要删，也删不了
        songImg：http://p1.music.126.net/AAKrMZu-zyunLRqAMO9JlA==/109951166577890720.jpg?param=130y130
        而本系统添加的歌曲时，图片是存储在云存储桶里的，需要删除
        songImg：https://pony-1312090731.cos.ap-beijing.myqcloud.com/yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
        */
        String songImg = song.getSongImg();

        // 删除云存储桶里的歌曲图片
        if (songImg!=null && !"".equals(songImg)){
            //删除云存储桶里的歌曲 图片（网易的不用删）, 只需要判断是否以 https 开头就行
            if (songImg.startsWith("https")){
                //songImgKey: 20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
                String songImgKey = songImg.substring(songImg.indexOf("images/")+7);
                //文件夹名 + songImgKey yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
                TXCloudFileUtils.del(imgPath+songImgKey);
            }
        }
    }

    /**
     * 删除云存储桶里的歌曲 mp3 文件
     * @param song 待删除歌曲
     */
    public void deleteTXCosSongMp3(Song song){
        //songUrl: https://pony-1312090731.cos.ap-beijing.myqcloud.com/yxy/songs/2023040604095235161c90e3594a19b440308cc27284a4.mp3
        String songUrl = song.getSongUrl();

        // 删除云存储桶里的歌曲 mp3 文件
        if (songUrl!=null && !"".equals(songUrl)){
            // 得到存储桶歌曲 .mp3 文件的key(即文件名称)
            //songUrlKey: 2023040604095235161c90e3594a19b440308cc27284a4.mp3
            String songUrlKey = songUrl.substring(songUrl.indexOf("songs/")+6);
            //文件夹名 + songUrlKey yxy/songs/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
            TXCloudFileUtils.del(songPath+songUrlKey);
        }
    }


    /**
     * 根据歌曲id，查询单个歌曲信息
     * @param id 歌曲id
     * @return
     */
    @Override
    public R selectOneById(Integer id) {
        LambdaQueryWrapper<Song> qw = new LambdaQueryWrapper<>();
        qw.eq(Song::getSongId, id);
        Song song = songMapper.selectOne(qw);
        return R.success().message("根据id，查询单个歌曲数据").data("song", song);
    }

    /**
     * 修改歌曲基本信息
     * @param song
     * @return
     */
    @Override
    public R updateSong(Song song) {
        // 1、修改前，先删除云端数据
        LambdaQueryWrapper<Song> qw = new LambdaQueryWrapper<>();
        qw.eq(Song::getSongId, song.getSongId());
        Song selectOne = songMapper.selectOne(qw);
        deleteTXCosSongImg(selectOne);
        /*
        * 根据 歌曲id 修改歌曲名 和 歌曲状态
        * 对于 歌曲的 图片地址， 歌词， MP3文件地址，在调用上传 api 时会修改
        * 这里不需要处理
        * */
        LambdaUpdateWrapper<Song> uw = new LambdaUpdateWrapper<>();
        uw.eq(Song::getSongId, song.getSongId());
        uw.set(Song::getSongName, song.getSongName());
        uw.set(Song::getSongStatus, song.getSongStatus());
        uw.set(Song::getSongImg, song.getSongImg());
        uw.set(Song::getSongLyric, song.getSongLyric());
        uw.set(Song::getSongUrl, song.getSongUrl());

        int updateResult = songMapper.update(song, uw);
        if (updateResult==1){
            return R.success().message("歌曲修改成功");
        }
        return R.error().message("歌曲修改失败，系统错误，请联系管理员");
    }

    /**
     * 批量删除
     * @param ids 歌曲 id数组
     * @return
     */
    @Override
    public R deleteSongBatch(List<Integer> ids) {
        for (Integer id: ids) {
            LambdaQueryWrapper<Song> qw = new LambdaQueryWrapper<>();
            qw.eq(Song::getSongId, id);
            int deleteResult = songMapper.delete(qw);
            //删除歌曲 歌手的关联信息
            songMapper.deleteSingerBySongId(id);
            //删除歌曲 专辑的关联信息
            songMapper.deleteAlbumBySongId(id);

            if (deleteResult!=1){
                return R.error().message("批量删除失败，系统错误，请联系管理员");
            }
        }
        return R.success().message("批量删除成功");
    }

    /**
     * 为 歌曲添加歌手信息和此歌手的专辑信息
     * @param songId 待添加的歌曲id
     * @param singerId  要添加的歌手id ，-1 表示用户没传
     * @param albumId  要添加的歌手id ，-1 表示用户没传，就不用添加了
     * @return
     */
    @Override
    public R addSingerAlbumForSong(Integer songId, Integer singerId, Integer albumId) {
        //添加前先删除 song 有 关联的 歌手信息
        songMapper.deleteSingerBySongId(songId);
        Integer addSingerResult = songMapper.addSingerForSong(songId, singerId);
        if (addSingerResult!=1){
            return R.error().message("歌曲添加歌手失败，系统错误，请联系管理员");
        }
        // 用户要为歌曲添加专辑
        if (albumId != -1){
            // 添加前先删除
            songMapper.deleteAlbumBySongId(songId);
            // 添加
            Integer addAlbumResult = songMapper.addAlbumForSong(songId, albumId);
            if (addAlbumResult!=1){
                return R.error().message("歌曲添加专辑失败，系统错误，请联系管理员");
            }
        }
        return R.success().message("歌曲添加歌手、专辑成功");
    }
}
